home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Atari Mega Archive 1
/
Atari Mega Archive - Volume 1.iso
/
lists
/
gem
/
l_1199
/
969
< prev
next >
Wrap
Internet Message Format
|
1994-08-27
|
6KB
Date: Fri, 22 Jul 94 03:16 CDT
From: ekl@sdf.lonestar.org (Evan K. Langlois)
To: gem-list@world.std.com
Subject: BUTTON CODE
Precedence: bulk
/* NOTE This program uses printf, and it really shouldn't. But I want
you to compile this and see that you really can wait on any buttons
and that a right-left combination is NOT needed. I used printf so
I wouldn't have to post a RSC file. This program is only meant to
demonstrate how to recieve mouse button events. It is NOT meant to
show how to properly code a GEM application - see ST-Pro-GEM for good
GEM programming.
*/
#include <osbind.h>
#include <gemfast.h>
#include <aesbind.h>
#include <stdio.h>
void main (void) {
register int i, bb;
int quit = 0, mes[8], ky, t, press, x, y, b, d, nb, k, rc, app_id;
app_id = appl_init();
/* This may help multitasking, and/or the double-click-event bug, and it
sets up some defaults, like starting button mask. Its not needed */
evnt_multi(0x23,1,1,1,0,0,0,0,0,0,0,0,0,0,mes,150L,&x,&y,&nb,&k,&ky,&t);
while (!quit) {
/* HOW TO WAIT ON ANY BUTTON !
The second parameter to evnt_multi tells how many button clicks to
wait for. This is the maximum number, so make it big. If you want to
recieve a double click, make it at least 2. Big numbers are no problem.
The high byte is set ON (OR with 0x0100 or add 256) to make this a
reverse button event - we wait for a negative condition. I'm not sure
if GEM will still delay for a second click if you set the low byte to 1,
and we NEED this delay for "presses" so leave the byte at 2 to be safe.
The third parameter tells the mask of buttons that you are waiting on.
ALL BUTTONS ARE WAITED FOR! You wait for all buttons, not either button.
Normally you use 0x01 for the left button, but when using the negative
event, you can handle more buttons than one, so make it 0x7F for all 8!
The third is a button mask, 0 for up, 1 for down, for each button, same
as the button return word, and the button mask in the previous parameter.
Normally this is a 1, waiting for the left mouse button to be down. In
this trick you make it a 0 (all buttons up).
The trick is simple, wait for ALL buttons to NOT be up. The event fires
when ALL the buttons are not up - or when any one button is down. Now,
a common mistake is to leave the third parameter a constant, which means
the evnt_multi falls through as long as the person holds the button down.
Make the parameter the old button mask, and you'll get an event when any
one button changes state. Note that you'll get two events for one click
unless you change the button mask and remember that on a normal click,
the mouse has been checked for a double-click, so &b is when the event
occured, not the current button state.
By using graf_mkstate to poll the current state of the button, we can
tell if the button is already up. If its already released, then we have
a single click, and we change our mask so that we don't get a button
up event. Otherwise, we see if there is a draggable object or menu.
*/
rc = evnt_multi (0x03, 0x102,0x7F,nb, 0,0,0,0,0, 0,0,0,0,0, mes,
0L, &x, &y, &b, &k, &ky, &t);
if (rc & MU_KEYBD) /* Keyboard event, quit app */
quit = 1;
if (rc & MU_BUTTON) {
/* See what window to "send" the click to here, with
* wind_find() and a custom lookup - how is up to you.
*
* graf_mkstate() is called here because it sets the
* evnt_multi input button state and gives us the
* current state to compare to the evnt_multi output
*/
graf_mkstate (&d,&d,&press,&d); /* New button state */
/* Here we test and compare button masks, bit-by-bit! */
for (i=0; i < 8; i++) {
bb = (1 << i); /* A mask ! */
if ((nb & bb) != (b & bb)) { /* An event? */
if (b & bb)
if (press & bb)
printf ("Press button #%d @ %d,%d\n",i,x,y);
else if (t > 1)
printf ("D-Click button #%d @ %d,%d\n",i,x,y);
else
printf ("Click button #%d @ %d,%d\n",i,x,y);
else
printf ("Release button #%d @ %d,%d\n",i,x,y);
}
}
nb = press;
}
}
appl_exit();
Pterm0();
}
/* A press means begin drag or group select (button 0/left) or pop-up a
* menu (button 1/right) or it may mean to begin some rectangle tricks. A
* graphics program would use a press to turn on mouse rectangles, and
* would apply a brush when the rectangle event fires, and would turn off
* the rectangle event handling when a release event occurs. A release
* event signals where a pop-up menu was selected, or where an item was
* dropped.
*
* Remember that you did not get an event unless the button mask put in
* to evnt_multi is different from that coming out of evnt_multi.
*
* A window top is a click if there is a selectable and completely
* UNOBSCURED object under the mouse pointer in the window being topped.
* Otherwise top the window! Objects must be completely visible!
*
*
* A press can wait on rectangles do the operation on a release within
* the object, while entering and exiting the object selects and deselects
* the object, much like form_do() - try it!
*
* Don't call graf_mkstate or another polling routine - always use the
* mouse coordinates at the time of the event! The code above is very
* non-modal. You can pop-up a menu with a right button, then realizing
* you should have selected an icon, you click it with the left button,
* then release the right button on the menu item you prefer. Button
* events are completely independant! You are also free to allow the
* right button OR left button to select buttons (nice for left handed
* users).
*
* Enjoy the code!
*/